#pragma once
#include "Array.h"
#include "Puntero.h"
#include "Ciudad.h"
#include "Matriz.h"
#include "Camino.h"
#include "ListaImp.h"
#include "IteradorListaImp.h"
#include "Iterador.h"
#include "AristaKruskal.h"
#include "CiudadFuncionHash.h"
#include "PaisFuncionHash.h"
#include "FuncionIgualesCiudad.h"
#include "FuncionIgualesPais.h"
#include "ColaImp.h"
#include "Tupla.h"
#include "Pais.h"
#include "Recurso.h"


class Mapa
{
public:
	Mapa(int cant);
	~Mapa(void);
	void vacio();
	void agregarCiudad(Puntero<Ciudad> c);
	void eliminarVertice(Ciudad  c);
	void agregarCamino(Puntero<Ciudad> origen, Puntero<Ciudad> destino, int costo, int Km);
	void eliminarCamino(Ciudad origen, Ciudad destino);
	int cantidadVertices();
	int numero(Ciudad c);
	Puntero<Ciudad> nombre(int num);
	bool hayCamino(int origen, int destino);
	void ListarMapaRecursivo(int cOri, Array<bool> conocidos,int cSig,int totalCosto,int totalKm);
	void ListarMapaRecursivo2(int cOri, Array<bool> conocidos,int cSig,int totalCosto,int totalKm);
	void ListarMapa(Puntero<Ciudad> c);
	Puntero<Tupla<Puntero<Ciudad>,Puntero<Recurso>>> Importar(Puntero<Ciudad> c,Puntero<Recurso>,int cantidad);
	Puntero<Iterador<Puntero<Ciudad>>> CaminoMasCorto(Puntero<Ciudad> ciudadOrigen,Puntero<Ciudad> ciudadDestino);
	bool Conectividad();
	void unir(int v, int w, Array<int> ciudad);
	void EncolarAristas(Puntero<Cola<Puntero<AristaKruskal>>> &cola);
	Puntero<ColaImp<Puntero<AristaKruskal>>>  Kruskal(Array<int> Ciudad,Puntero<ColaImp<Puntero<AristaKruskal>>> aristas);
	int ciudad(int v, Array<int> ciudad);
	void ListarKruskal(Puntero<ColaImp<Puntero<AristaKruskal>>> cola);
	void ListarKruskalPais(Puntero<ColaImp<Puntero<AristaKruskal>>> cola);
	bool ConexionBarata(Puntero<Iterador<Tupla<pPais,pCiudad>>> ciudades);
	Puntero<Iterador<Puntero<Recurso>>> SeleccionarRec(Puntero<Ciudad> c,int k);
	void OrdenarArray(Array<Puntero<Recurso>> &vector,int tope);
	void RecolectarAux(int ciudadActual,Puntero<ListaImp<Puntero<Ciudad>>> &caminoActual,int k,Cadena nombreRec,int& mejorCosto,int costoActual,Puntero<ListaImp<Puntero<Ciudad>>>&solucion,int cantRec,int& mejCantRec,Array<bool> &conocidos);
	void RutasEntrePaisesAux(int ,Puntero<ListaImp<Puntero<Ciudad>>> &,Puntero<ListaImp<Puntero<ListaImp<Puntero<Ciudad>>>>>&,Array<bool>&,Cadena);
	Puntero<ListaImp<Puntero<Ciudad>>> Recolectar(Puntero<Ciudad> c,Cadena recurso,int k);

	Puntero<ListaImp<Puntero<ListaImp<Puntero<Ciudad>>>>> RutasEntrePaises(Puntero<Ciudad> c,Cadena nombrePaisD);
	Tupla<int,Puntero<Hash<Puntero<Pais>, int>>>  ValorMapa();



private:
	Puntero<Hash<Puntero<Ciudad>, int>> Ei;
	Puntero<Hash<Puntero<Pais>, int>> EiPaises;
	Array<Puntero<Pais>>  iEPaises;
	Puntero<ListaImp<Puntero<Ciudad>>> listaCaminoMasCorto;
	//Tarea**	arregloNumero;
	Array<Puntero<Ciudad>> iE;
	Matriz<Puntero<Camino>> matriz;
	Matriz<Puntero<Camino>> distancia;
	Matriz<int> caminosCriticos;
	Puntero<Array<int>> grado;
	Puntero<Array<int>> orden;
	Array<bool> distraConocido;
	Array<int> distraCamino;
	Array<int> dijstraDistancia;
	int cantMax;
	int cantActual;
	int cantActualPaises;
	Matriz<bool>caminos;
	Puntero<ListaImp<Puntero<Recurso>>> listaRecUtilizados;


	//metodos privados
	void inicializarCaminos();
	void cierreTransitivo();
	void inicializarGrado();
	void inicializarOrden();
	void inicializarDijstra();
	int buscarVerticeGradoCero();
	void mostrarOrdenTopologico();
	void inicializarCalculosDeCaminos();
	void Floyd();
	void Dijkstra(int origen);
	int miniDist();
	Puntero<ColaImp<Puntero<AristaKruskal>>> buscarAristaEntrePaises();
	//int caminosMasLargos(int origen, int destino, int actual,Lista* caminoActual, int mejorCosto, Pila* mejoresCaminos);
	//Lista* adyacentes(int origen);
	int costo(int origen, int destino);

};
